﻿#include "CaptureCallback.h"
#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QDir>
#include <SimpleScreenCaptureHandler.h>
#include <random>

#include <osgGA/NodeTrackerManipulator>
#include <osgParticle/ParticleSystem>
#include <osgDB/Registry>
#include <QMessageBox>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    osgWidget = new osgQOpenGLWidget(ui->widget);          // 指定osg窗口显示位置
    osgWidget->setGeometry(ui->widget->geometry());        // 指定osg窗口显示大小
    m_fileName= "D:/AGongZuo/"
                "build-shuangboduan-Desktop_Qt_5_12_10_MSVC2017_64bit-Release/model/"
                "object/plane2/plane2.flt";
    qDebug()<<m_fileName;
}


osg::ref_ptr<osg::MatrixTransform> MainWindow::matChange(osg::Vec3 position,osg::Vec3 pose,double scale)
{
    //SRT -》矩阵变换后实际执行从右到左TRS
    osg::ref_ptr<osg::MatrixTransform> mat_node =new osg::MatrixTransform;
    mat_node->setMatrix(
                osg::Matrix::scale( scale, scale, scale ) *
                osg::Matrix::rotate(osg::DegreesToRadians(pose.x()), osg::Vec3d(1.0, 0.0, 0.0),
                                    osg::DegreesToRadians(pose.y()), osg::Vec3d(0.0, 1.0, 0.0),
                                    osg::DegreesToRadians(pose.z()), osg::Vec3d(0.0, 0.0, 1.0)) *
                osg::Matrix::translate(osg::Vec3(position.x(), position.y(), position.z()))
                );
    return mat_node;
}
//添加粒子
void MainWindow::addParticle(QString nodeFile, osg::Vec3 position, osg::Vec3 pose, double scale)
{

    osg::ref_ptr<osg::Node> node = osgDB::readNodeFile(nodeFile.toStdString());
    osg::ref_ptr<osg::MatrixTransform> node_mt =matChange(position,pose,scale);



    node_mt->addChild(node);
    //auto outlineNode = addOutlineEffect(node_mt);
    root->addChild(node_mt);
}

void MainWindow::SaveOsgImage(QString filePath,osg::Camera* camera)
{
    camera->setFinalDrawCallback(new CaptureCallback(filePath.toStdString()));
}
void MainWindow::on_pushButton_2_clicked()
{
    SaveOsgImage("E:/temp",pViewer->getCamera());
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::initOSG()
{
    pViewer = osgWidget->getOsgViewer();
    root = new osg::Group();
    pViewer->setCameraManipulator(new osgGA::TrackballManipulator);

    // 加载模型
    node = osgDB::readNodeFile(m_fileName.toStdString());
    // 添加模型
    root->addChild(node);

//    node1=osgDB::readNodeFile("D:/AGongZuo/build-shuangboduan-Desktop_Qt_5_12_10_MSVC2017_64bit-Release/model/particleEffects/plume.osg");
//    node2=osgDB::readNodeFile("D:/AGongZuo/build-shuangboduan-Desktop_Qt_5_12_10_MSVC2017_64bit-Release/model/particleEffects/plume.osg");

//    root->addChild(node1);
//    root->addChild(node2);


    pViewer->setSceneData(root);
    pViewer->addEventHandler(new osgViewer::StatsHandler);
    osgWidget->setFocus();
}


void MainWindow::on_pushButton_clicked()
{
    initOSG();
}

void MainWindow::setMatrix(osg::MatrixTransform* mat_node, double x, double y, double z)
{
    mat_node->setMatrix(
        osg::Matrix::scale( 1, 1, 1 ) *
        osg::Matrix::rotate(osg::DegreesToRadians(0.0), osg::Vec3d(1.0, 0.0, 0.0),
                            osg::DegreesToRadians(0.0), osg::Vec3d(0.0, 1.0, 0.0),
                            osg::DegreesToRadians(180.0), osg::Vec3d(0.0, 0.0, 1.0)) *
        osg::Matrix::translate(osg::Vec3(x, y, z))
    );
    qDebug()<<"懂了";
}
void MainWindow::on_pushButton_3_clicked()
{



    double x = ui->doubleSpinBox_5->value();
    double y = ui->doubleSpinBox_6->value();
    double z = ui->doubleSpinBox_7->value();
//    osg::MatrixTransform* mat_node=new osg::MatrixTransform;
//    mat_node->addChild(node1);
//    setMatrix(mat_node,x,y,z);


    double scale = ui->doubleSpinBox_8->value();
    double yaw = ui->doubleSpinBox_15->value();
    double pitch = ui->doubleSpinBox_16->value();
    double roll = ui->doubleSpinBox_17->value();
    addParticle("D:/AGongZuo/"
                "build-shuangboduan-Desktop_Qt_5_12_10_MSVC2017_64bit-Release/"
                "model/particleEffects/plume.osg",
                osg::Vec3(x,y,z),osg::Vec3(yaw,pitch,roll),scale);
}

void MainWindow::on_pushButton_4_clicked()
{
    osgDB::writeNodeFile(*root, "./chu/test.osg");
}
void MainWindow::on_pushButton_5_clicked()
{
    int w = 640, h = 480;
    QImage darkImg(w, h, QImage::Format_Grayscale8);
    QImage flatImg(w, h, QImage::Format_Grayscale8);

    std::mt19937 rng;
    std::uniform_int_distribution<int> distOffset(0, 10);
    std::normal_distribution<float> distGain(1.0f, 0.05f);

    int baseRadiance = 200;

    // 填充暗场图
    for (int y = 0; y < h; y++) {
        uchar* line = darkImg.scanLine(y);
        for (int x = 0; x < w; x++) {
            int offset = distOffset(rng);
            line[x] = static_cast<uchar>(offset);
        }
    }

    // 填充平场图
    for (int y = 0; y < h; y++) {
        uchar* lineFlat = flatImg.scanLine(y);
        uchar* lineDark = darkImg.scanLine(y);
        for (int x = 0; x < w; x++) {
            int D = lineDark[x];
            float gain = distGain(rng);
            int value = static_cast<int>(D + gain * baseRadiance);
            value = qBound(0, value, 255);
            lineFlat[x] = static_cast<uchar>(value);
        }
    }


    // 保存或直接使用 darkImg, flatImg 作为校准图像
    darkImg.save("dark.png");
    flatImg.save("flat.png");

}
osg::ref_ptr<osgGA::NodeTrackerManipulator> trackerManipulator;

void MainWindow::on_pushButton_6_clicked()
{
    if (!root.valid() || root->getNumChildren() == 0)
        return;

    // 循环切换目标索引
    if (++currentIndex >= root->getNumChildren())
        currentIndex = 0;

    // 获取当前目标节点
    osg::Node* targetNode = root->getChild(currentIndex);
    if (!targetNode) return;

    // 创建或更新跟踪器
    if (!trackerManipulator) {
        trackerManipulator = new osgGA::NodeTrackerManipulator;

        // 设置跟踪模式 (默认值，显式设置确保正确)
        trackerManipulator->setTrackerMode(osgGA::NodeTrackerManipulator::NODE_CENTER_AND_ROTATION);

        // 设置旋转模式 (使相机始终看向目标)
        trackerManipulator->setRotationMode(osgGA::NodeTrackerManipulator::TRACKBALL);
    }

    // 设置跟踪节点
    trackerManipulator->setTrackNode(targetNode);

    // 计算最佳距离 (可选，自动调整视距)
    const osg::BoundingSphere& bs = targetNode->getBound();
    double distance = bs.valid() ? bs.radius() * 3.0 : 5.0;
    trackerManipulator->setDistance(distance);

    if (pViewer) {
        pViewer->setCameraManipulator(trackerManipulator);
    }
}
